/*
 * File    : Utilities.java
 * Created : 24-Mar-2004
 * By      : parg
 * 
 * Azureus - a Java Bittorrent client
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details ( see the LICENSE file ).
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.gudy.azureus2.plugins.utils;

/**
 * @author parg
 *
 */

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;

import org.gudy.azureus2.plugins.PluginException;
import org.gudy.azureus2.plugins.ddb.DistributedDatabase;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloader;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderException;
import org.gudy.azureus2.plugins.utils.resourcedownloader.ResourceDownloaderFactory;
import org.gudy.azureus2.plugins.utils.resourceuploader.ResourceUploaderFactory;
import org.gudy.azureus2.plugins.utils.search.SearchException;
import org.gudy.azureus2.plugins.utils.search.SearchInitiator;
import org.gudy.azureus2.plugins.utils.search.SearchProvider;
import org.gudy.azureus2.plugins.utils.security.SESecurityManager;
import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionException;
import org.gudy.azureus2.plugins.utils.subscriptions.SubscriptionManager;
import org.gudy.azureus2.plugins.utils.xml.rss.RSSFeed;
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentException;
import org.gudy.azureus2.plugins.utils.xml.simpleparser.SimpleXMLParserDocumentFactory;

public interface Utilities {
    public String getAzureusUserDir();

    public String getAzureusProgramDir();

    public boolean isCVSVersion();

    public boolean isWindows();

    public boolean isLinux();

    public boolean isSolaris();

    public boolean isOSX();

    /**
     * @return Whether the OS is a unix flavor (linux, bsd, aix, etc)
     * 
     * @since 2.4.0.3
     */
    boolean isUnix();

    /**
     * @return Whether the OS is FreeBSD
     * 
     * @note Up to at least v2.4.0.2, the FreeBSD port has identified itself to azureus as Linux and not FreeBSD
     * 
     * @since 2.4.0.3
     */
    boolean isFreeBSD();

    public InputStream getImageAsStream(String image_name);

    public Semaphore getSemaphore();

    public Monitor getMonitor();

    public ByteBuffer allocateDirectByteBuffer(int size);

    public void freeDirectByteBuffer(ByteBuffer buffer);

    public PooledByteBuffer allocatePooledByteBuffer(int size);

    public PooledByteBuffer allocatePooledByteBuffer(byte[] data);

    /**
     * 
     * @param data
     *            must be b-encodable
     * @return
     */

    public PooledByteBuffer allocatePooledByteBuffer(Map data)

    throws IOException;

    public Formatters getFormatters();

    public LocaleUtilities getLocaleUtilities();

    /**
     * Creates a <code>UTTimer</code> instance. It will be configured for non-lightweight tasks by default.
     * 
     * @param name
     *            Name for the UTTimer object.
     * @return A UTTimer instance.
     */
    public UTTimer createTimer(String name);

    /**
     * Creates a <code>UTTimer</code> instance.
     * 
     * @param name
     *            Name for the UTTimer object.
     * @param lightweight
     *            If <code>true</code>, it indicates that this timer will be used to perform small lightweight tasks. If <code>false</code>, it
     *            indicates that this timer will be used to perform expensive tasks. This allows Azureus to create the appropriate amount of resources
     *            to manage this timer.
     * @return A UTTimer instance.
     */
    public UTTimer createTimer(String name, boolean lightweight);

    /**
     * Creates a <code>UTTimer</code> instance.
     * 
     * @param name
     *            Name for the UTTimer object.
     * @param priority
     *            The Thread.<i>XXX_</i>PRIORITY value to use.
     * @return A UTTimer instance.
     */
    public UTTimer createTimer(String name, int priority);

    /**
     * create and run a thread for the target. This will be a daemon thread so that its existence doesn't interfere with Azureus closedown
     * 
     * @param name
     * @param target
     */

    public void createThread(String name, Runnable target);

    /**
     * create a child process and executes the supplied command line. The child process will not inherit any open handles on Windows, which does
     * happen if Runtime is used directly. This relies on the Platform plugin, if this is not installed then this will fall back to using Runtime.exec
     * 
     * @param command_line
     */

    public void createProcess(String command_line)

    throws PluginException;

    public ResourceDownloaderFactory getResourceDownloaderFactory();

    public ResourceUploaderFactory getResourceUploaderFactory();

    public SESecurityManager getSecurityManager();

    public SimpleXMLParserDocumentFactory getSimpleXMLParserDocumentFactory();

    /**
     * @deprecated
     * @param is
     * @return
     * @throws SimpleXMLParserDocumentException
     */

    public RSSFeed getRSSFeed(InputStream is)

    throws SimpleXMLParserDocumentException;

    public RSSFeed getRSSFeed(URL source_url, InputStream is)

    throws SimpleXMLParserDocumentException;

    public RSSFeed getRSSFeed(URL feed_location)

    throws ResourceDownloaderException, SimpleXMLParserDocumentException;

    /**
     * @deprecated
     * @param feed_location
     * @return
     * @throws ResourceDownloaderException
     * @throws SimpleXMLParserDocumentException
     */

    public RSSFeed getRSSFeed(ResourceDownloader feed_location)

    throws ResourceDownloaderException, SimpleXMLParserDocumentException;

    public RSSFeed getRSSFeed(URL source_url, ResourceDownloader feed_location)

    throws ResourceDownloaderException, SimpleXMLParserDocumentException;

    /**
     * Returns a public IP address of the machine or null if it can't be determined
     */

    public InetAddress getPublicAddress();

    public InetAddress getPublicAddress(boolean ipv6);

    /**
     * attempts a reverse DNS lookup of an address, null if it fails
     * 
     * @param address
     * @return
     */

    public String reverseDNSLookup(InetAddress address);

    /**
     * Get the current system time, like System.currentTimeMillis(), only the time lookup is cached for performance reasons.
     * 
     * @return current system time
     */
    public long getCurrentSystemTime();

    public ByteArrayWrapper createWrapper(byte[] data);

    /**
     * create a dispatcher that will queue runnable items until either the limit is reached or the dispatcher hasn't had an entry added for the
     * defined idle time
     * 
     * @param idle_dispatch_time
     *            milliseconds
     * @param max_queue_size
     *            0 -> infinite
     * @return
     */

    public AggregatedDispatcher createAggregatedDispatcher(long idle_dispatch_time, long max_queue_size);

    public AggregatedList createAggregatedList(AggregatedListAcceptor acceptor, long idle_dispatch_time, long max_queue_size);

    /**
     * 
     * @return Map read from config file, or empty HashMap if error
     */
    public Map readResilientBEncodedFile(File parent_dir, String file_name, boolean use_backup);

    public void writeResilientBEncodedFile(File parent_dir, String file_name, Map data, boolean use_backup);

    public void deleteResilientBEncodedFile(File parent_dir, String file_name, boolean use_backup);

    /**
     * Compares two version strings for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to,
     * or greater than the second.
     * <p>
     * Example:<br>
     * compareVersions("1.1.0.0", "1.1.2.0"); // - compareVersions("1.1.0.0", "1.1.0"); // 0 compareVersions("1.1.1.1", "1.1.1"); // +
     * 
     * @param v1
     *            the first version string to be compared
     * @param v2
     *            the second version string to be compared
     * @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.
     * 
     * @since 2.3.0.7
     */
    public int compareVersions(String v1, String v2);

    /**
     * Converts a file name so that all characters in the file name are compatible with the underlying filesystem. This includes quote characters,
     * back and forwarded slashes, newline characters and so on.
     * 
     * <p>
     * 
     * Note - this is only intended for file names, rather than file paths.
     * 
     * @param f_name
     *            File name to convert.
     * @return Converted file name.
     */
    public String normaliseFileName(String f_name);

    /**
     * Adds a low priority task that will be scheduled at some point after existing tasks have completed. In particular a system task exists that will
     * block subsequent ones until after UI initialisation is complete. Plugins can therefore use this to schedule initialisation actions to occur
     * after UI init is complete.
     * 
     * @since 3.0.5.3
     * @return
     */

    public DelayedTask createDelayedTask(Runnable r);

    public void registerSearchProvider(SearchProvider provider)

    throws SearchException;

    public void unregisterSearchProvider(SearchProvider provider)

    throws SearchException;

    public SearchInitiator getSearchInitiator()

    throws SearchException;

    public SubscriptionManager getSubscriptionManager()

    throws SubscriptionException;

    public FeatureManager getFeatureManager();

    public boolean supportsPowerStateControl(int state);

    public void addPowerManagementListener(PowerManagementListener listener);

    public void removePowerManagementListener(PowerManagementListener listener);

    public List<LocationProvider> getLocationProviders();

    public void addLocationProvider(LocationProvider provider);

    public void removeLocationProvider(LocationProvider provider);

    public void addLocationProviderListener(LocationProviderListener listener);

    public void removeLocationProviderListener(LocationProviderListener listener);

    public void registerJSONRPCServer(JSONServer server);

    public void unregisterJSONRPCServer(JSONServer server);

    public void registerJSONRPCClient(JSONClient client);

    public void unregisterJSONRPCClient(JSONClient client);

    public List<DistributedDatabase> getDistributedDatabases(String[] networks);

    public interface JSONServer {
        public String getName();

        public List<String> getSupportedMethods();

        public Map call(String method, Map args)

        throws PluginException;
    }

    public interface JSONClient {
        public void serverRegistered(JSONServer server);

        public void serverUnregistered(JSONServer server);
    }
}
